package com.xlh.service.courseTest.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.xlh.dao.courseTest.CourseTestPaperModelMapper;
import com.xlh.dto.course.ChapterBasicDTO;
import com.xlh.dto.courseTest.model.ModelIncludeChapterDTO;
import com.xlh.dto.courseTest.model.ModelNotChapterDTO;
import com.xlh.enums.course.ChapterEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.param.courseTest.PaperModelInsertParam;
import com.xlh.pojo.course.ChapterBasic;
import com.xlh.pojo.course.Course;
import com.xlh.pojo.courseTest.CourseTestPaperModel;
import com.xlh.pojo.courseTest.CourseTestPaperModelExample;
import com.xlh.service.course.ChapterService;
import com.xlh.service.course.CourseService;
import com.xlh.service.courseTest.PaperModelService;
import com.xlh.service.courseTest.QuestionRepositoryService;
import com.xlh.util.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhr 2019/3/2
 */
@Service
public class PaperModelServiceImpl implements PaperModelService {

    @Autowired
    private ChapterService chapterService;
    @Autowired
    private QuestionRepositoryService questionRepositoryService;
    @Autowired
    private CourseService courseService;

    @Autowired
    private CourseTestPaperModelMapper modelMapper;

    @Override
    public List<CourseTestPaperModel> getPaperModel(Boolean modelType, Long courseId) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        // 查询模板
        List<CourseTestPaperModel> modelList = selectPaperModel(modelType, courseId, userId);

        // 为带章节模板添加进章节信息
        // 获取章节的映射集
        Set<Long> chapterIdSet = Sets.newHashSet();
        for (CourseTestPaperModel model : modelList) {
            if (model.getIsChapterModel()) {
                List<ModelIncludeChapterDTO> list = JSONArray.parseArray(model.getContent()).toJavaList(ModelIncludeChapterDTO.class);
                chapterIdSet.addAll(list.stream().map(ModelIncludeChapterDTO::getId).collect(Collectors.toSet()));
            }
        }
        List<ChapterBasic> chapterBasics = chapterService.getChapterBasic(null, Lists.newArrayList(chapterIdSet), null, ChapterEnum.CHAPTER);
        Map<Long, String> chapterIdMap = chapterBasics.stream().collect(Collectors.toMap(ChapterBasic::getId, ChapterBasic::getName));
        // 回填章节名称
        for (CourseTestPaperModel model : modelList) {
            if (model.getIsChapterModel()) {
                List<ModelIncludeChapterDTO> list = JSONArray.parseArray(model.getContent()).toJavaList(ModelIncludeChapterDTO.class);
                list.forEach(dto -> dto.setName(chapterIdMap.get(dto.getId())));
                model.setContent(JSONArray.toJSONString(list));
            }

        }
        return modelList;
    }

    @Override
    public void addPaperModel(PaperModelInsertParam param, Long courseId) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        // 判断是否重复提交
        // 查询条件：教师id、模板类型、模板详情，如果是章节模板需要课程id
        if (addPaperModelDuplicated(param, courseId, userId)) {
            throw new GlobalException("已有相同模板");
        }

        insert(param, courseId, userId);
    }

    @Override
    public void deletePaperModel(Long modelId, Long courseId) {
        Course course = courseService.getCourseById(courseId);
        Long userId = course.getUserId();

        // 判断是否具备删除权限
        CourseTestPaperModel courseTestPaperModel = modelMapper.selectByPrimaryKey(modelId);
        // 如果模板制作人不是自己或者模板为预制模板，则没有删除权限
        if (courseTestPaperModel.getIsPreset() || !Objects.equal(courseTestPaperModel.getTeacherId(), userId)) {
            throw new GlobalException("无删除权限");
        }

        modelMapper.deleteByPrimaryKey(modelId);
    }

    @Override
    public CourseTestPaperModel selectByPrimaryKey(Long id) {
        return modelMapper.selectByPrimaryKey(id);
    }

    @Override
    public Boolean checkModel(Long modelId, Long courseId) {
        CourseTestPaperModel model = modelMapper.selectByPrimaryKey(modelId);

        if (model == null) {
            throw new GlobalException("参数错误");
        }

        if (model.getIsChapterModel()) {
            List<ModelIncludeChapterDTO> list = JSONArray.parseArray(model.getContent(), ModelIncludeChapterDTO.class);

            list.forEach(dto -> {
                List<ModelNotChapterDTO> countList = questionRepositoryService.questionCount(courseId, dto.getId());
                checkCount(dto.getContent(), countList);
            });
        } else {
            List<ModelNotChapterDTO> list = JSONArray.parseArray(model.getContent(), ModelNotChapterDTO.class);

            List<ModelNotChapterDTO> countList = questionRepositoryService.questionCount(courseId, null);
            checkCount(list, countList);
        }

        return true;
    }

    private void checkCount(List<ModelNotChapterDTO> list, List<ModelNotChapterDTO> countList) {
        Map<Integer, Integer> typeCountMap = countList.stream().collect(Collectors.toMap(ModelNotChapterDTO::getType, ModelNotChapterDTO::getCount));
        list.forEach(dto -> {
            Integer count = typeCountMap.get(dto.getType());
            if (count == null || dto.getCount() > count) {
                throw new GlobalException("当前题库题目数量不足,无法使用该模板");
            }
        });
    }

    /**
     * 查询教师模板
     *
     * @param isChapterModel 是否章节模板
     * @param courseId       课程id，如果是章节模板，则需要此参数操作
     * @param userId         登录用户id
     * @return 教师模板集合
     */
    private List<CourseTestPaperModel> selectPaperModel(Boolean isChapterModel, Long courseId, Long userId) {
        // 查询所有的模板（教师本人及预置模板）
        CourseTestPaperModelExample example = new CourseTestPaperModelExample();
        // 教师本人的模板
        CourseTestPaperModelExample.Criteria criteria1 = example.createCriteria();
        criteria1.andTeacherIdEqualTo(userId).andIsChapterModelEqualTo(isChapterModel);
        // 预制模板
        CourseTestPaperModelExample.Criteria criteria2 = example.createCriteria();
        criteria2.andTeacherIdIsNull().andIsChapterModelEqualTo(isChapterModel);
        // 若需要查询章节模板（isChapterModel为true或者null的时候），需要拼接课程id做查询条件
        if (isChapterModel) {
            criteria1.andCourseIdEqualTo(courseId);
            criteria2.andCourseIdEqualTo(courseId);
        }

        // 合并查询条件
        example.or(criteria1);
        example.or(criteria2);
        // 执行查询
        List<CourseTestPaperModel> courseTestPaperModels = modelMapper.selectByExample(example);
        List<CourseTestPaperModel> resultChapterBasicDTOS= Lists.newArrayList();

        // 1. 过滤已经删除的章节信息
        List<ChapterBasicDTO> chapterBasicDTOS = chapterService.listChapter(courseId);

        List<Long> chapterIds = chapterBasicDTOS.stream().map(ChapterBasicDTO::getId).collect(Collectors.toList());


        for (CourseTestPaperModel courseTestPaperModel : courseTestPaperModels) {

            List<ModelIncludeChapterDTO> list = JSONArray.parseArray(courseTestPaperModel.getContent()).toJavaList(ModelIncludeChapterDTO.class);
            if(courseTestPaperModel.getIsChapterModel()){
                list = list.stream().filter(dto -> chapterIds.contains(dto.getId())).collect(Collectors.toList());

                if(CollectionUtil.isNotEmpty(list)){
                    courseTestPaperModel.setContent(JSONArray.toJSONString(list));
                    resultChapterBasicDTOS.add(courseTestPaperModel);
                }
            }else{
                resultChapterBasicDTOS.add(courseTestPaperModel);
            }
        }

        return resultChapterBasicDTOS;
    }

    /**
     * 插入模板数据
     *
     * @param param    模板数据参数
     * @param courseId 课程id
     * @param userId   登录用户id
     */
    private void insert(PaperModelInsertParam param, Long courseId, Long userId) {
        CourseTestPaperModel model = BeanUtil.transform(CourseTestPaperModel.class, param);
        model.setTeacherId(userId);
        if (param.getIsChapterModel()) {
            model.setCourseId(courseId);
        }
        modelMapper.insertSelective(model);
    }

    /**
     * 判断添加的模板是否已重复
     *
     * @param param    请求参数
     * @param courseId 课程id
     * @param userId   登录用户id
     * @return 是否重复状态
     */
    private boolean addPaperModelDuplicated(PaperModelInsertParam param, Long courseId, Long userId) {
        CourseTestPaperModelExample example = new CourseTestPaperModelExample();
        CourseTestPaperModelExample.Criteria criteria = example.createCriteria();
        criteria.andTeacherIdEqualTo(userId)
                .andIsChapterModelEqualTo(param.getIsChapterModel())
                .andContentEqualTo(param.getContent());
        if (param.getIsChapterModel()) {
            criteria.andCourseIdEqualTo(courseId);
        }
        return modelMapper.countByExample(example) > 0;
    }
}
